package Simulation;

import java.util.Scanner;

import Config.Config;

/**
 * Simulates the flu
 * 
 * @author Amir BEN SLIMANE
 */
public class Simulation extends Manager {
    private Move move;
    private Infection infection;
    private Map map;
    private SwitchStatus switchStatus;
    private int health, sick, contagious, recovery, dead;

    /**
     * Builder's Simulation
     */
    public Simulation() {
        Scanner sc = new Scanner(System.in);
        initialize(sc);
        this.map.intitializePeople();
        iterate(sc);
    }

    private void initialize(Scanner sc) {
        System.out
                .println("Welcome to Frosh Project !\nHow many infected want you start the simulation ? There are "
                        + (Config.PERSON_POPULATION + Config.ANIMAL_POPULATION)
                        + " people.");
        int infected = sc.nextInt();
        this.map = new Map(infected);
        this.move = new Move(this.map);
        this.infection = new Infection(this.map);
        this.switchStatus = new SwitchStatus(this.map);

    }

    private void iterate(Scanner sc) {
        System.out.println("Simulation will be represented on this map\n"
                + this.map.toString());
        boolean next = true;
        int cpt = 1;
        do {

            this.counter();
            if (getContagious() == 0 && getRecovery() == 0 && getSick() == 0) {
                break;
            }
            this.switchStatus.checkToSwitch();
            this.infection.lookArround();
            this.move.moveEverybodyRandom();
            System.out.println("Day : " + cpt + " - Healthy : "
                    + this.getHealth() + " - Sick : " + this.getSick()
                    + " - Contagious : " + this.getContagious()
                    + " - Recovery : " + this.getRecovery() + " - Dead : "
                    + this.getDead());
            System.out.println(this.map.toString());
            writeStatus(this.map);
            cpt++;
            
            //it enables to have a delay between each map
            try {
                Thread.sleep(Config.INFORMATION_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
        } while (next);
        System.out.println(this.map.toString());
        System.out.println("End of simulation ! After " + cpt
                + " days, remains " + this.getHealth() + " survivors !");
    }

    /**
     * Account the occurrence of status
     */
    private void counter() {
        this.setHealth(0);
        this.setContagious(0);
        this.setSick(0);
        this.setRecovery(0);
        this.setDead(0);
        for (int x = 0; x < Config.MAP_HEIGTH; x++) {
            for (int y = 0; y < Config.MAP_LENGTH; y++) {
                switch (this.map.getMapSimulation()[x][y].getStatus()) {
                case Healthy:
                    this.setHealth(this.getHealth() + 1);
                    break;
                case Contagious:
                    this.setContagious(this.getContagious() + 1);
                    break;
                case Sick:
                    this.setSick(this.getSick() + 1);
                    break;
                case Recovering:
                    this.setRecovery(this.getRecovery() + 1);
                    break;
                case Dead:
                    this.setDead(this.getDead() + 1);
                    break;
                default:
                    break;
                }
            }
        }
    }

    /**
     * @return the health
     */
    private int getHealth() {
        return health;
    }

    /**
     * @param health
     *            the health to set
     */
    private void setHealth(int health) {
        this.health = health;
    }

    /**
     * @return the sick
     */
    private int getSick() {
        return sick;
    }

    /**
     * @param sick
     *            the sick to set
     */
    private void setSick(int sick) {
        this.sick = sick;
    }

    /**
     * @return the contagious
     */
    private int getContagious() {
        return contagious;
    }

    /**
     * @param contagious
     *            the contagious to set
     */
    private void setContagious(int contagious) {
        this.contagious = contagious;
    }

    /**
     * @return the recovery
     */
    private int getRecovery() {
        return recovery;
    }

    /**
     * @param recovery
     *            the recovery to set
     */
    private void setRecovery(int recovery) {
        this.recovery = recovery;
    }

    /**
     * @return the dead
     */
    private int getDead() {
        return dead;
    }

    /**
     * @param dead
     *            the dead to set
     */
    private void setDead(int dead) {
        this.dead = dead;
    }
}
